#ifndef OBJECT_H
#define OBJECT_H

#include "defs.h"
#include "model/vertex.h"
#include "model/halfedge.h"
#include "model/face.h"
#include "model/matrixtransformation.h"
#include "model/mixin/limits.h"
#include "model/lighting.h"

#include "method/shading.h"

#include <vector>
#include <string>

struct Face;
struct HalfEdge;

class Object: public Limits {

public:


protected:
    friend class PerspectiveProjection;

    //-------------------------------------------------------------//
    //                          ATTRIBUTES                         //
    //-------------------------------------------------------------//

protected:
    std::vector<Vertex*> vertexs;
    std::vector<HalfEdge*> edges;
    std::vector<Face*> faces;

    Lighting properties;
    bool visible;

    //-------------------------------------------------------------//
    //                          METHODS                            //
    //-------------------------------------------------------------//

    /**
     * Obtém a referência ao vértice informado
     */
    Vertex* makeVertex(const Vertex &vertex);

    /**
     * Obtém referências aos vertices informados.
     * Caso os pontos não pertencam ao objeto, o método irá adicioná-los.
     */
    std::vector<Vertex*> makeVertex(const std::vector<Vertex> &vertexs);

public:
    enum Exceptions {
        InsuficentPoints,
        InvalidFile,
    };

    Object();
    Object(const Object& object);
    Object(const std::string &filename);
    virtual ~Object();

    virtual Face* add(const std::vector<Vertex> &makeVertex);

    const std::vector<const Face*>& getFaces() const;
    const std::vector<const HalfEdge*>& getEdges() const;
    const std::vector<const Vertex*>& getVertex() const;
    const std::vector<Vertex*>& getVertex();

    void apply(const MatrixTransformation &matrix);
    void save(const std::string &filename) const;

    const Lighting &getLightProperties() const;

    void setLightProperties(const Lighting &properties);

    void setVisible(bool b);

    bool isVisible() const;

    light_t getKar();
    light_t getKag();
    light_t getKab();
    light_t getKdr();
    light_t getKdg();
    light_t getKdb();
    light_t getKsr();
    light_t getKsg();
    light_t getKsb();
    light_t getN();

    void setKar(light_t k);
    void setKag(light_t k);
    void setKab(light_t k);
    void setKdr(light_t k);
    void setKdg(light_t k);
    void setKdb(light_t k);
    void setKsr(light_t k);
    void setKsg(light_t k);
    void setKsb(light_t k);
    void setN(light_t n);
};


#endif // OBJECT_H

